import ctypes


class DLLError(Exception):
    pass


class DynamicLinkLibrary:

    errors = {
        0x00000000: "ok",
    }

    def __init__(self, path):
        self.path = path
        self.dll = ctypes.cdll.LoadLibrary(self.path)

    def __call__(self, name, *args):
        rtn_code = getattr(self.dll, name)(*args)
        self._check(rtn_code)

    def _check(self, code, ok=0):
        """Overwrite this by super(Heir, self)._check(code, YOUR_OK_VALUE)
        Params:
            - code: int
                return value of a dll funcall
            - ok: int
                value that indicates the funcall is successful
        Return:
            - no return value (None)
        """
        if code != ok:
            raise DLLError("[0x%08x] %s" % (code, self.errors[code]))

    def _load(self, path):
        """Load the export functions list from header file"""
        pass

    def _wrap(self, fndict):
        """Wrap the dll exported function to Python function
        Params:
            - fndict: dict
                {
                    "name": "function",
                    "return": "int *",
                    "args": [
                        ("first", "int"),
                        ("second", "char *"),
                        ...
                    ]
                }
        Return:
            - setattr(self, name, fn)
        """
        pass

    def _parse(self, functions):
        """Parse the header file and each function info"""
        pass
